home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 May / EnigmA AMIGA RUN 18 (1997)(G.R. Edizioni)(IT)[!][issue 1997-05][EAR-CD II].iso / ghost / gs403src_png.lha / gs4.03 / libpng / pngread.c < prev    next >
C/C++ Source or Header  |  1996-06-05  |  25KB  |  800 lines

  1.  
  2. /* pngread.c - read a png file
  3.  
  4.    libpng 1.0 beta 3 - version 0.89
  5.    For conditions of distribution and use, see copyright notice in png.h
  6.    Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  7.    May 25, 1996
  8.    */
  9.  
  10. #define PNG_INTERNAL
  11. #include "png.h"
  12.  
  13. /* Create a png structure for reading, and allocate any memory needed. */
  14. png_structp
  15. png_create_read_struct(png_const_charp user_png_ver, voidp error_ptr,
  16.    png_error_ptr warn_fn, png_error_ptr error_fn)
  17. {
  18.    png_structp png_ptr;
  19.  
  20.    if ((png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG)) == NULL)
  21.    {
  22.       return (png_structp)NULL;
  23.    }
  24.  
  25.    if (setjmp(png_ptr->jmpbuf))
  26.    {
  27.       png_large_free(png_ptr, png_ptr->zbuf);
  28.       png_free(png_ptr, png_ptr->zstream);
  29.       png_destroy_struct(png_ptr);
  30.       return (png_structp)NULL;
  31.    }
  32.  
  33.    png_set_error_fn(png_ptr, error_ptr, warn_fn, error_fn);
  34.  
  35.    if (user_png_ver == NULL || strcmp(user_png_ver, png_libpng_ver))
  36.    {
  37.       if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0])
  38.       {
  39.          png_error(png_ptr, "Incompatible libpng versions");
  40.       }
  41.       else
  42.       {
  43.          png_warning(png_ptr, "Different libpng versions");
  44.       }
  45.    }
  46.  
  47.    /* initialize zbuf - compression buffer */
  48.    png_ptr->zbuf_size = PNG_ZBUF_SIZE;
  49.    png_ptr->zbuf = png_large_malloc(png_ptr, png_ptr->zbuf_size);
  50.  
  51.    png_ptr->zstream = (z_stream *)png_malloc(png_ptr, sizeof (z_stream));
  52.    png_ptr->zstream->zalloc = png_zalloc;
  53.    png_ptr->zstream->zfree = png_zfree;
  54.    png_ptr->zstream->opaque = (voidpf)png_ptr;
  55.  
  56.    switch (inflateInit(png_ptr->zstream))
  57.    {
  58.      case Z_OK: /* Do nothing */ break;
  59.      case Z_MEM_ERROR:
  60.      case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error"); break;
  61.      case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error"); break;
  62.      default: png_error(png_ptr, "Unknown zlib error");
  63.    }
  64.  
  65.    png_ptr->zstream->next_out = png_ptr->zbuf;
  66.    png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
  67.  
  68.    png_set_read_fn(png_ptr, NULL, NULL);
  69.  
  70.    png_ptr->do_free |= PNG_FREE_STRUCT;
  71.  
  72.    return (png_ptr);
  73. }
  74.  
  75.  
  76. /* initialize png structure for reading, and allocate any memory needed */
  77. /* This interface is depreciated in favour of the png_create_read_struct() */
  78. void
  79. png_read_init(png_structp png_ptr)
  80. {
  81.    jmp_buf tmp_jmp;  /* to save current jump buffer */
  82.  
  83.    /* save jump buffer and error functions */
  84.    png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
  85.  
  86.    /* reset all variables to 0 */
  87.    png_memset(png_ptr, 0, sizeof (png_struct));
  88.  
  89.    /* restore jump buffer */
  90.    png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
  91.  
  92.    /* initialize zbuf - compression buffer */
  93.    png_ptr->zbuf_size = PNG_ZBUF_SIZE;
  94.    png_ptr->zbuf = png_large_malloc(png_ptr, png_ptr->zbuf_size);
  95.  
  96.    png_ptr->zstream = (z_stream *)png_malloc(png_ptr, sizeof (z_stream));
  97.    png_ptr->zstream->zalloc = png_zalloc;
  98.    png_ptr->zstream->zfree = png_zfree;
  99.    png_ptr->zstream->opaque = (voidpf)png_ptr;
  100.  
  101.    switch (inflateInit(png_ptr->zstream))
  102.    {
  103.      case Z_OK: /* Do nothing */ break;
  104.      case Z_MEM_ERROR:
  105.      case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory"); break;
  106.      case Z_VERSION_ERROR: png_error(png_ptr, "zlib version"); break;
  107.      default: png_error(png_ptr, "Unknown zlib error");
  108.    }
  109.  
  110.    png_ptr->zstream->next_out = png_ptr->zbuf;
  111.    png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
  112.  
  113.    png_set_read_fn(png_ptr, NULL, NULL);
  114. }
  115.  
  116. /* read the information before the actual image data. */
  117. void
  118. png_read_info(png_structp png_ptr, png_infop info)
  119. {
  120.    png_byte chunk_start[8];
  121.    png_uint_32 length;
  122.  
  123.    png_read_data(png_ptr, chunk_start, 8);
  124.    if (!png_check_sig(chunk_start, 8))
  125.    {
  126.       if (!png_check_sig(chunk_start, 4))
  127.          png_error(png_ptr, "Not a PNG file");
  128.       else
  129.          png_error(png_ptr, "PNG file corrupted by ASCII conversion");
  130.    }
  131.  
  132.    while (1)
  133.    {
  134.       png_uint_32 crc;
  135.  
  136.       png_read_data(png_ptr, chunk_start, 8);
  137.       length = png_get_uint_32(chunk_start);
  138.       png_reset_crc(png_ptr);
  139.       png_calculate_crc(png_ptr, chunk_start + 4, 4);
  140.       if (!png_memcmp(chunk_start + 4, png_IHDR, 4))
  141.          png_handle_IHDR(png_ptr, info, length);
  142.       else if (!png_memcmp(chunk_start + 4, png_PLTE, 4))
  143.          png_handle_PLTE(png_ptr, info, length);
  144.       else if (!png_memcmp(chunk_start + 4, png_IDAT, 4))
  145.       {
  146.          if (!(png_ptr->mode & PNG_HAVE_IHDR))
  147.             png_error(png_ptr, "Missing IHDR before IDAT");
  148.          else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
  149.                   !(png_ptr->mode & PNG_HAVE_PLTE))
  150.             png_error(png_ptr, "Missing PLTE before IDAT");
  151.  
  152.          png_ptr->idat_size = length;
  153.          png_ptr->mode |= PNG_HAVE_IDAT;
  154.          break;
  155.       }
  156.       else if (!png_memcmp(chunk_start + 4, png_IEND, 4))
  157.          png_error(png_ptr, "No image in file");
  158. #if defined(PNG_READ_gAMA_SUPPORTED)
  159.       else if (!png_memcmp(chunk_start + 4, png_gAMA, 4))
  160.          png_handle_gAMA(png_ptr, info, length);
  161. #endif
  162. #if defined(PNG_READ_sBIT_SUPPORTED)
  163.       else if (!png_memcmp(chunk_start + 4, png_sBIT, 4))
  164.          png_handle_sBIT(png_ptr, info, length);
  165. #endif
  166. #if defined(PNG_READ_cHRM_SUPPORTED)
  167.       else if (!png_memcmp(chunk_start + 4, png_cHRM, 4))
  168.          png_handle_cHRM(png_ptr, info, length);
  169. #endif
  170. #if defined(PNG_READ_tRNS_SUPPORTED)
  171.       else if (!png_memcmp(chunk_start + 4, png_tRNS, 4))
  172.          png_handle_tRNS(png_ptr, info, length);
  173. #endif
  174. #if defined(PNG_READ_bKGD_SUPPORTED)
  175.       else if (!png_memcmp(chunk_start + 4, png_bKGD, 4))
  176.          png_handle_bKGD(png_ptr, info, length);
  177. #endif
  178. #if defined(PNG_READ_hIST_SUPPORTED)
  179.       else if (!png_memcmp(chunk_start + 4, png_hIST, 4))
  180.          png_handle_hIST(png_ptr, info, length);
  181. #endif
  182. #if defined(PNG_READ_pHYs_SUPPORTED)
  183.       else if (!png_memcmp(chunk_start + 4, png_pHYs, 4))
  184.          png_handle_pHYs(png_ptr, info, length);
  185. #endif
  186. #if defined(PNG_READ_oFFs_SUPPORTED)
  187.       else if (!png_memcmp(chunk_start + 4, png_oFFs, 4))
  188.          png_handle_oFFs(png_ptr, info, length);
  189. #endif
  190. #if defined(PNG_READ_tIME_SUPPORTED)
  191.       else if (!png_memcmp(chunk_start + 4, png_tIME, 4))
  192.          png_handle_tIME(png_ptr, info, length);
  193. #endif
  194. #if defined(PNG_READ_tEXt_SUPPORTED)
  195.       else if (!png_memcmp(chunk_start + 4, png_tEXt, 4))
  196.          png_handle_tEXt(png_ptr, info, length);
  197. #endif
  198. #if defined(PNG_READ_zTXt_SUPPORTED)
  199.       else if (!png_memcmp(chunk_start + 4, png_zTXt, 4))
  200.          png_handle_zTXt(png_ptr, info, length);
  201. #endif
  202.       else
  203.       {
  204.          if (chunk_start[4] < 41 || chunk_start[4] > 122  ||
  205.              (chunk_start[4] > 90 && chunk_start[4] < 97) ||
  206.              chunk_start[5] < 41 || chunk_start[5] > 122  ||
  207.              (chunk_start[5] > 90 && chunk_start[5] < 97) ||
  208.              chunk_start[6] < 41 || chunk_start[6] > 122  ||
  209.              (chunk_start[6] > 90 && chunk_start[6] < 97) ||
  210.              chunk_start[7] < 41 || chunk_start[7] > 122  ||
  211.              (chunk_start[7] > 90 && chunk_start[7] < 97))
  212.          {
  213.             char msg[45];
  214.  
  215.             sprintf(msg, "Invalid chunk type 0x%02X 0x%02X 0x%02X 0x%02X",
  216.                chunk_start[4], chunk_start[5], chunk_start[6], chunk_start[7]);
  217.             png_error(png_ptr, msg);
  218.          }
  219.  
  220.          if ((chunk_start[4] & 0x20) == 0)
  221.          {
  222.             char msg[40];
  223.  
  224.             sprintf(msg, "Unknown critical chunk %c%c%c%c",
  225.                chunk_start[4], chunk_start[5], chunk_start[6], chunk_start[7]);
  226.             png_error(png_ptr, msg);
  227.          }
  228.  
  229.          png_crc_skip(png_ptr, length);
  230.       }
  231.       png_read_data(png_ptr, chunk_start, 4);
  232.       crc = png_get_uint_32(chunk_start);
  233.       if (((crc ^ 0xffffffffL) & 0xffffffffL) != (png_ptr->crc & 0xffffffffL))
  234.          png_error(png_ptr, "Bad CRC value");
  235.    }
  236. }
  237.  
  238. /* optional call to update the users info structure */
  239. void
  240. png_read_update_info(png_structp png_ptr, png_infop info)
  241. {
  242.    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
  243.       png_read_start_row(png_ptr);
  244.    png_read_transform_info(png_ptr, info);
  245. }
  246.  
  247. /* initialize palette, background, etc, after transformations
  248.    are set, but before any reading takes place.  This allows
  249.    the user to obtail a gamma corrected palette, for example.
  250.    If the user doesn't call this, we will do it ourselves. */
  251. void
  252. png_start_read_image(png_structp png_ptr)
  253. {
  254.    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
  255.       png_read_start_row(png_ptr);
  256. }
  257.  
  258. void
  259. png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
  260. {
  261.    int ret;
  262.    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
  263.       png_read_start_row(png_ptr);
  264.  
  265. #if defined(PNG_READ_INTERLACING_SUPPORTED)
  266.    /* if interlaced and we do not need a new row, combine row and return */
  267.    if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
  268.    {
  269.       switch (png_ptr->pass)
  270.       {
  271.          case 0:
  272.             if (png_ptr->row_number & 7)
  273.             {
  274.                if (dsp_row)
  275.                   png_combine_row(png_ptr, dsp_row,
  276.                      png_pass_dsp_mask[png_ptr->pass]);
  277.                png_read_finish_row(png_ptr);
  278.                return;
  279.             }
  280.             break;
  281.          case 1:
  282.             if ((png_ptr->row_number & 7) || png_ptr->width < 5)
  283.             {
  284.                if (dsp_row)
  285.                   png_combine_row(png_ptr, dsp_row,
  286.                      png_pass_dsp_mask[png_ptr->pass]);
  287.                png_read_finish_row(png_ptr);
  288.                return;
  289.             }
  290.             break;
  291.          case 2:
  292.             if ((png_ptr->row_number & 7) != 4)
  293.             {
  294.                if (dsp_row && (png_ptr->row_number & 4))
  295.                   png_combine_row(png_ptr, dsp_row,
  296.                      png_pass_dsp_mask[png_ptr->pass]);
  297.                png_read_finish_row(png_ptr);
  298.                return;
  299.             }
  300.             break;
  301.          case 3:
  302.             if ((png_ptr->row_number & 3) || png_ptr->width < 3)
  303.             {
  304.                if (dsp_row)
  305.                   png_combine_row(png_ptr, dsp_row,
  306.                      png_pass_dsp_mask[png_ptr->pass]);
  307.                png_read_finish_row(png_ptr);
  308.                return;
  309.             }
  310.             break;
  311.          case 4:
  312.             if ((png_ptr->row_number & 3) != 2)
  313.             {
  314.                if (dsp_row && (png_ptr->row_number & 2))
  315.                   png_combine_row(png_ptr, dsp_row,
  316.                      png_pass_dsp_mask[png_ptr->pass]);
  317.                png_read_finish_row(png_ptr);
  318.                return;
  319.             }
  320.             break;
  321.          case 5:
  322.             if ((png_ptr->row_number & 1) || png_ptr->width < 2)
  323.             {
  324.                if (dsp_row)
  325.                   png_combine_row(png_ptr, dsp_row,
  326.                      png_pass_dsp_mask[png_ptr->pass]);
  327.                png_read_finish_row(png_ptr);
  328.                return;
  329.             }
  330.             break;
  331.          case 6:
  332.             if (!(png_ptr->row_number & 1))
  333.             {
  334.                png_read_finish_row(png_ptr);
  335.                return;
  336.             }
  337.             break;
  338.       }
  339.    }
  340. #endif
  341.  
  342.    if (!(png_ptr->mode & PNG_HAVE_IDAT))
  343.       png_error(png_ptr, "Invalid attempt to read row data");
  344.  
  345.    png_ptr->zstream->next_out = png_ptr->row_buf;
  346.    png_ptr->zstream->avail_out = (uInt)png_ptr->irowbytes;
  347.    do
  348.    {
  349.       if (!(png_ptr->zstream->avail_in))
  350.       {
  351.          while (!png_ptr->idat_size)
  352.          {
  353.             png_byte buf[4];
  354.             png_uint_32 crc;
  355.  
  356.             png_read_data(png_ptr, buf, 4);
  357.             crc = png_get_uint_32(buf);
  358.             if (((crc ^ 0xffffffffL) & 0xffffffffL) !=
  359.                (png_ptr->crc & 0xffffffffL))
  360.                png_error(png_ptr, "Bad CRC value");
  361.  
  362.             png_read_data(png_ptr, buf, 4);
  363.             png_ptr->idat_size = png_get_uint_32(buf);
  364.             png_reset_crc(png_ptr);
  365.  
  366.             png_crc_read(png_ptr, buf, 4);
  367.             if (png_memcmp(buf, png_IDAT, 4))
  368.                png_error(png_ptr, "Not enough IDATs for image");
  369.          }
  370.          png_ptr->zstream->avail_in = (uInt)png_ptr->zbuf_size;
  371.          png_ptr->zstream->next_in = png_ptr->zbuf;
  372.          if (png_ptr->zbuf_size > png_ptr->idat_size)
  373.             png_ptr->zstream->avail_in = (uInt)png_ptr->idat_size;
  374.          png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream->avail_in);
  375.          png_ptr->idat_size -= png_ptr->zstream->avail_in;
  376.       }
  377.       ret = inflate(png_ptr->zstream, Z_PARTIAL_FLUSH);
  378.       if (ret == Z_STREAM_END)
  379.       {
  380.          if (png_ptr->zstream->avail_out || png_ptr->zstream->avail_in ||
  381.             png_ptr->idat_size)
  382.             png_error(png_ptr, "Extra compressed data");
  383.          png_ptr->mode |= PNG_AT_LAST_IDAT;
  384.          png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
  385.          break;
  386.       }
  387.       if (ret != Z_OK)
  388.          png_error(png_ptr, png_ptr->zstream->msg ? png_ptr->zstream->msg :
  389.                    "Decompression error");
  390.    } while (png_ptr->zstream->avail_out);
  391.  
  392.    png_ptr->row_info.color_type = png_ptr->color_type;
  393.    png_ptr->row_info.width = png_ptr->iwidth;
  394.    png_ptr->row_info.channels = png_ptr->channels;
  395.    png_ptr->row_info.bit_depth = png_ptr->bit_depth;
  396.    png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
  397.    png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
  398.       (png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
  399.  
  400.    png_read_filter_row(png_ptr, &(png_ptr->row_info),
  401.       png_ptr->row_buf + 1, png_ptr->prev_row + 1,
  402.       (int)(png_ptr->row_buf[0]));
  403.  
  404.    png_memcpy(png_ptr->prev_row, png_ptr->row_buf, (png_size_t)png_ptr->rowbytes + 1);
  405.  
  406.    if (png_ptr->transformations)
  407.       png_do_read_transformations(png_ptr);
  408.  
  409. #if defined(PNG_READ_INTERLACING_SUPPORTED)
  410.    /* blow up interlaced rows to full size */
  411.    if (png_ptr->interlaced &&
  412.       (png_ptr->transformations & PNG_INTERLACE))
  413.    {
  414.       if (png_ptr->pass < 6)
  415.          png_do_read_interlace(&(png_ptr->row_info),
  416.             png_ptr->row_buf + 1, png_ptr->pass);
  417.  
  418.       if (dsp_row)
  419.          png_combine_row(png_ptr, dsp_row,
  420.             png_pass_dsp_mask[png_ptr->pass]);
  421.       if (row)
  422.          png_combine_row(png_ptr, row,
  423.             png_pass_mask[png_ptr->pass]);
  424.    }
  425.    else
  426. #endif
  427.    {
  428.       if (row)
  429.          png_combine_row(png_ptr, row, 0xff);
  430.       if (dsp_row)
  431.          png_combine_row(png_ptr, dsp_row, 0xff);
  432.    }
  433.    png_read_finish_row(png_ptr);
  434. }
  435.  
  436. /* read a one or more rows of image data.   If the image is interlaced,
  437.    and png_set_interlace_handling() has been called, the rows need to
  438.    to contain the contents of the rows from the previous pass.  If
  439.    the image has alpha or transparency, and png_handle_alpha() has been
  440.    called, the rows contents must be initialized to the contents of the
  441.    screen.  row holds the actual image, and pixels are placed in it
  442.    as they arrive.  If the image is displayed after each pass, it will
  443.    appear to "sparkle" in.  display_row can be used to display a
  444.    "chunky" progressive image, with finer detail added as it becomes
  445.    available.  If you do not want this "chunky" display, you may pass
  446.    NULL for display_rows.  If you do not want the sparkle display, and
  447.    you have not called png_handle_alpha(), you may pass NULL for rows.
  448.    If you have called png_handle_alpha(), and the image has either an
  449.    alpha channel or a transparency chunk, you must provide a buffer for
  450.    rows.  In this case, you do not have to provide a display_rows buffer
  451.    also, but you may.  If the image is not interlaced, or if you have
  452.    not called png_set_interlace_handling(), the display_row buffer will
  453.    be ignored, so pass NULL to it. */
  454.  
  455. void
  456. png_read_rows(png_structp png_ptr, png_bytepp row,
  457.    png_bytepp display_row, png_uint_32 num_rows)
  458. {
  459.    png_uint_32 i;
  460.    png_bytepp rp;
  461.    png_bytepp dp;
  462.  
  463.    rp = row;
  464.    dp = display_row;
  465.    for (i = 0; i < num_rows; i++)
  466.    {
  467.       png_bytep rptr;
  468.       png_bytep dptr;
  469.  
  470.       if (rp)
  471.          rptr = *rp;
  472.       else
  473.          rptr = NULL;
  474.       if (dp)
  475.          dptr = *dp;
  476.       else
  477.          dptr = NULL;
  478.       png_read_row(png_ptr, rptr, dptr);
  479.       if (row)
  480.          rp++;
  481.       if (display_row)
  482.          dp++;
  483.    }
  484. }
  485.  
  486. /* read the image.  If the image has an alpha channel or a transparency
  487.    chunk, and you have called png_handle_alpha(), you will need to
  488.    initialize the image to the current image that png will be overlaying.
  489.    We set the num_rows again here, in case it was incorrectly set in
  490.    png_read_start_row() by a call to png_read_update_info() or
  491.    png_start_read_image() if png_set_interlace_handling() wasn't called
  492.    prior to either of these functions like it should have been.  You only
  493.    need to call this function once.  If you desire to have an image for
  494.    each pass of a interlaced image, use png_read_rows() instead */
  495. void
  496. png_read_image(png_structp png_ptr, png_bytepp image)
  497. {
  498.    png_uint_32 i;
  499.    int pass, j;
  500.    png_bytepp rp;
  501.  
  502.    pass = png_set_interlace_handling(png_ptr);
  503.  
  504.    png_ptr->num_rows = png_ptr->height; /* Make sure this is set correctly */
  505.  
  506.    for (j = 0; j < pass; j++)
  507.    {
  508.       rp = image;
  509.       for (i = 0; i < png_ptr->height; i++)
  510.       {
  511.          png_read_row(png_ptr, *rp, NULL);
  512.          rp++;
  513.       }
  514.    }
  515. }
  516.  
  517. /* read the end of the png file.  Will not read past the end of the
  518.    file, will verify the end is accurate, and will read any comments
  519.    or time information at the end of the file, if info is not NULL. */
  520. void
  521. png_read_end(png_structp png_ptr, png_infop info)
  522. {
  523.    png_byte chunk_start[8];
  524.    png_uint_32 length;
  525.    png_uint_32 crc;
  526.  
  527.    png_read_data(png_ptr, chunk_start, 4);
  528.    crc = png_get_uint_32(chunk_start);
  529.    if (((crc ^ 0xffffffffL) & 0xffffffffL) !=
  530.       (png_ptr->crc & 0xffffffffL))
  531.       png_error(png_ptr, "Bad CRC value");
  532.  
  533.    do
  534.    {
  535.       png_read_data(png_ptr, chunk_start, 8);
  536.       length = png_get_uint_32(chunk_start);
  537.       png_reset_crc(png_ptr);
  538.       png_calculate_crc(png_ptr, chunk_start + 4, 4);
  539.  
  540.       if (!png_memcmp(chunk_start + 4, png_IHDR, 4))
  541.       {
  542.          png_error(png_ptr, "Invalid IHDR after IDAT");
  543.       }
  544.       else if (!png_memcmp(chunk_start + 4, png_PLTE, 4))
  545.       {
  546.          png_error(png_ptr, "Invalid PLTE after IDAT");
  547.       }
  548.       else if (!png_memcmp(chunk_start + 4, png_gAMA, 4))
  549.       {
  550.          png_error(png_ptr, "Invalid gAMA after IDAT");
  551.       }
  552.       else if (!png_memcmp(chunk_start + 4, png_sBIT, 4))
  553.       {
  554.          png_error(png_ptr, "Invalid sBIT after IDAT");
  555.       }
  556.       else if (!png_memcmp(chunk_start + 4, png_cHRM, 4))
  557.       {
  558.          png_error(png_ptr, "Invalid cHRM after IDAT");
  559.       }
  560.       else if (!png_memcmp(chunk_start + 4, png_tRNS, 4))
  561.       {
  562.          png_error(png_ptr, "Invalid tRNS after IDAT");
  563.       }
  564.       else if (!png_memcmp(chunk_start + 4, png_bKGD, 4))
  565.       {
  566.          png_error(png_ptr, "Invalid bKGD after IDAT");
  567.       }
  568.       else if (!png_memcmp(chunk_start + 4, png_hIST, 4))
  569.       {
  570.          png_error(png_ptr, "Invalid hIST after IDAT");
  571.       }
  572.       else if (!png_memcmp(chunk_start + 4, png_IDAT, 4))
  573.       {
  574.          if (length > 0 || png_ptr->mode & PNG_AFTER_IDAT)
  575.             png_error(png_ptr, "Too many IDAT's found");
  576.       }
  577.       else if (!png_memcmp(chunk_start + 4, png_pHYs, 4))
  578.       {
  579.          png_error(png_ptr, "Invalid pHYs after IDAT");
  580.       }
  581.       else if (!png_memcmp(chunk_start + 4, png_oFFs, 4))
  582.       {
  583.          png_error(png_ptr, "Invalid oFFs after IDAT");
  584.       }
  585. #if defined(PNG_READ_tIME_SUPPORTED)
  586.       else if (!png_memcmp(chunk_start + 4, png_tIME, 4))
  587.       {
  588.          png_ptr->mode |= PNG_AFTER_IDAT;
  589.  
  590.          if (info)
  591.             png_handle_tIME(png_ptr, info, length);
  592.          else
  593.             png_crc_skip(png_ptr, length);
  594.       }
  595. #endif
  596. #if defined(PNG_READ_tEXt_SUPPORTED)
  597.       else if (!png_memcmp(chunk_start + 4, png_tEXt, 4))
  598.       {
  599.          png_ptr->mode |= PNG_AFTER_IDAT;
  600.  
  601.          if (info)
  602.             png_handle_tEXt(png_ptr, info, length);
  603.          else
  604.             png_crc_skip(png_ptr, length);
  605.       }
  606. #endif
  607. #if defined(PNG_READ_zTXt_SUPPORTED)
  608.       else if (!png_memcmp(chunk_start + 4, png_zTXt, 4))
  609.       {
  610.          png_ptr->mode |= PNG_AFTER_IDAT;
  611.  
  612.          if (info)
  613.             png_handle_zTXt(png_ptr, info, length);
  614.          else
  615.             png_crc_skip(png_ptr, length);
  616.       }
  617. #endif
  618.       else if (!png_memcmp(chunk_start + 4, png_IEND, 4))
  619.       {
  620.          png_ptr->mode |= PNG_AFTER_IDAT;
  621.          png_ptr->mode |= PNG_AFTER_IEND;
  622.       }
  623.       else
  624.       {
  625.          if (chunk_start[4] < 41 || chunk_start[4] > 122  ||
  626.              (chunk_start[4] > 90 && chunk_start[4] < 97) ||
  627.              chunk_start[5] < 41 || chunk_start[5] > 122  ||
  628.              (chunk_start[5] > 90 && chunk_start[5] < 97) ||
  629.              chunk_start[6] < 41 || chunk_start[6] > 122  ||
  630.              (chunk_start[6] > 90 && chunk_start[6] < 97) ||
  631.              chunk_start[7] < 41 || chunk_start[7] > 122  ||
  632.              (chunk_start[7] > 90 && chunk_start[7] < 97))
  633.          {
  634.            png_error(png_ptr, "Invalid chunk type");
  635.          }
  636.  
  637.          if ((chunk_start[4] & 0x20) == 0)
  638.             png_error(png_ptr, "Unknown critical chunk");
  639.  
  640.          png_ptr->mode |= PNG_AFTER_IDAT;
  641.          png_crc_skip(png_ptr, length);
  642.       }
  643.       png_read_data(png_ptr, chunk_start, 4);
  644.       crc = png_get_uint_32(chunk_start);
  645.       if (((crc ^ 0xffffffffL) & 0xffffffffL) != (png_ptr->crc & 0xffffffffL))
  646.          png_error(png_ptr, "Bad CRC value");
  647.    } while (!(png_ptr->mode & PNG_AFTER_IEND));
  648. }
  649.  
  650. /* free all memory used by the read */
  651. void
  652. png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
  653.    png_infopp end_info_ptr)
  654. {
  655.    png_structp png_ptr = NULL;
  656.    png_infop info_ptr = NULL, end_info = NULL;
  657.  
  658.    if (png_ptr_ptr)
  659.       png_ptr = *png_ptr_ptr;
  660.  
  661.    if (info_ptr_ptr)
  662.       info_ptr = *info_ptr_ptr;
  663.  
  664.    if (end_info_ptr)
  665.       end_info = *end_info_ptr;
  666.  
  667.    png_read_destroy(png_ptr, info_ptr, end_info);
  668.  
  669.    if (info_ptr)
  670.    {
  671.       png_destroy_struct((voidp)info_ptr);
  672.       *info_ptr_ptr = (png_infop)NULL;
  673.    }
  674.  
  675.    if (end_info)
  676.    {
  677.       png_destroy_struct((voidp)end_info);
  678.       *end_info_ptr = (png_infop)NULL;
  679.    }
  680.  
  681.    if (png_ptr)
  682.    {
  683.       png_destroy_struct((voidp)png_ptr);
  684.       *png_ptr_ptr = (png_structp)NULL;
  685.    }
  686. }
  687.  
  688. /* free all memory used by the read (old) */
  689. void
  690. png_read_destroy(png_structp png_ptr, png_infop info, png_infop end_info)
  691. {
  692.    int i;
  693.    jmp_buf tmp_jmp;
  694.    png_error_ptr error_fn;
  695.    png_error_ptr warning_fn;
  696.    png_voidp error_ptr;
  697.  
  698.    if (info)
  699.    {
  700. #if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
  701.       for (i = 0; i < info->num_text; i++)
  702.       {
  703.          png_large_free(png_ptr, info->text[i].key);
  704.       }
  705.  
  706.       png_large_free(png_ptr, info->text);
  707. #endif
  708.       png_memset(info, 0, sizeof(png_info));
  709.    }
  710.  
  711.    if (end_info)
  712.    {
  713. #if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
  714.       for (i = 0; i < end_info->num_text; i++)
  715.       {
  716.          png_large_free(png_ptr, end_info->text[i].key);
  717.       }
  718.  
  719.       png_large_free(png_ptr, end_info->text);
  720. #endif
  721.       png_memset(end_info, 0, sizeof(png_info));
  722.    }
  723.  
  724.    png_large_free(png_ptr, png_ptr->zbuf);
  725.    png_large_free(png_ptr, png_ptr->row_buf);
  726.    png_large_free(png_ptr, png_ptr->prev_row);
  727. #if defined(PNG_READ_DITHER_SUPPORTED)
  728.    png_large_free(png_ptr, png_ptr->palette_lookup);
  729.    png_large_free(png_ptr, png_ptr->dither_index);
  730. #endif
  731. #if defined(PNG_READ_GAMMA_SUPPORTED)
  732.    png_large_free(png_ptr, png_ptr->gamma_table);
  733. #endif
  734. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  735.    png_large_free(png_ptr, png_ptr->gamma_from_1);
  736.    png_large_free(png_ptr, png_ptr->gamma_to_1);
  737. #endif
  738.    if (png_ptr->do_free & PNG_FREE_PALETTE)
  739.       png_large_free(png_ptr, png_ptr->palette);
  740. #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_bKGD_SUPPORTED)
  741.    if (png_ptr->do_free & PNG_FREE_TRANS)
  742.       png_large_free(png_ptr, png_ptr->trans);
  743. #endif
  744. #if defined(PNG_READ_hIST_SUPPORTED)
  745.    if (png_ptr->do_free & PNG_FREE_HIST)
  746.       png_large_free(png_ptr, png_ptr->hist);
  747. #endif
  748. #if defined(PNG_READ_GAMMA_SUPPORTED)
  749.    if (png_ptr->gamma_16_table)
  750.    {
  751.       for (i = 0; i < (1 << (8 - png_ptr->gamma_shift)); i++)
  752.       {
  753.          png_large_free(png_ptr, png_ptr->gamma_16_table[i]);
  754.       }
  755.    }
  756. #endif
  757. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  758.    png_large_free(png_ptr, png_ptr->gamma_16_table);
  759.    if (png_ptr->gamma_16_from_1)
  760.    {
  761.       for (i = 0; i < (1 << (8 - png_ptr->gamma_shift)); i++)
  762.       {
  763.          png_large_free(png_ptr, png_ptr->gamma_16_from_1[i]);
  764.       }
  765.    }
  766.    png_large_free(png_ptr, png_ptr->gamma_16_from_1);
  767.    if (png_ptr->gamma_16_to_1)
  768.    {
  769.       for (i = 0; i < (1 << (8 - png_ptr->gamma_shift)); i++)
  770.       {
  771.          png_large_free(png_ptr, png_ptr->gamma_16_to_1[i]);
  772.       }
  773.    }
  774.    png_large_free(png_ptr, png_ptr->gamma_16_to_1);
  775. #endif
  776.  
  777.    inflateEnd(png_ptr->zstream);
  778.    png_free(png_ptr, png_ptr->zstream);
  779. #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
  780.    png_large_free(png_ptr, png_ptr->save_buffer);
  781. #endif
  782.  
  783.    /* Save the important info out of the png_struct, in case it is
  784.     * being used again.
  785.     */
  786.    png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
  787.  
  788.    error_fn = png_ptr->error_fn;
  789.    warning_fn = png_ptr->warning_fn;
  790.    error_ptr = png_ptr->error_ptr;
  791.  
  792.    png_memset(png_ptr, 0, sizeof (png_struct));
  793.  
  794.    png_ptr->error_fn = error_fn;
  795.    png_ptr->warning_fn = warning_fn;
  796.    png_ptr->error_ptr = error_ptr;
  797.  
  798.    png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
  799. }
  800.